home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / security / shadow-3.1.4 / obscure.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-05  |  3.5 KB  |  208 lines

  1. /*
  2.  * Copyright 1989, 1990, 1991, 1992, John F. Haugh II
  3.  * All rights reserved.
  4.  *
  5.  * Permission is granted to copy and create derivative works for any
  6.  * non-commercial purpose, provided this copyright notice is preserved
  7.  * in all copies of source code, or included in human readable form
  8.  * and conspicuously displayed on all copies of object code or
  9.  * distribution media.
  10.  */
  11.  
  12. #include <ctype.h>
  13. #ifndef    BSD
  14. #include <string.h>
  15. #include <memory.h>
  16. #else
  17. #include <strings.h>
  18. #define    strchr    index
  19. #define    strrchr    rindex
  20. #endif
  21. #include "config.h"
  22.  
  23. #ifndef    lint
  24. static    char    sccsid[] = "@(#)obscure.c    3.6    20:37:32    3/7/92";
  25. #endif
  26.  
  27. extern    int    getdef_bool();
  28. extern    int    getdef_num();
  29.  
  30. #ifdef    NEED_STRSTR
  31. /*
  32.  * strstr - find substring in string
  33.  */
  34.  
  35. char *
  36. strstr (string, pattern)
  37. char    *string;
  38. char    *pattern;
  39. {
  40.     char    *cp;
  41.     int    len;
  42.  
  43.     len = strlen (pattern);
  44.  
  45.     for (cp = string;cp = strchr (cp, *pattern);) {
  46.         if (strncmp (cp, pattern, len) == 0)
  47.             return cp;
  48.  
  49.         cp++;
  50.     }
  51.     return 0;
  52. }
  53. #endif
  54.  
  55. /*
  56.  * Obscure - see if password is obscure enough.
  57.  *
  58.  *    The programmer is encouraged to add as much complexity to this
  59.  *    routine as desired.  Included are some of my favorite ways to
  60.  *    check passwords.
  61.  */
  62.  
  63. /*ARGSUSED*/
  64. int    obscure (old, new)
  65. char    *old;
  66. char    *new;
  67. {
  68.     int    i;
  69.     char    oldmono[32];
  70.     char    newmono[32];
  71.     char    wrapped[64];
  72.  
  73.     if (old[0] == '\0')
  74.         return (1);
  75.  
  76.     if ( strlen(new) < getdef_num("PASS_MIN_LEN", 0) ) {
  77.         printf ("Too short.  ");
  78.         return (0);
  79.     }
  80.  
  81.     /*
  82.      * Remaining checks are optional.
  83.      */
  84.     if ( !getdef_bool("OBSCURE_CHECKS_ENAB") )
  85.         return (1);
  86.  
  87.     for (i = 0;new[i];i++)
  88.         newmono[i] = tolower (new[i]);
  89.  
  90.     for (i = 0;old[i];i++)
  91.         oldmono[i] = tolower (old[i]); 
  92.  
  93.     if (strcmp (new, old) == 0) {    /* the same */
  94.         printf ("No Change.  ");
  95.         return (0);
  96.     }
  97.     if (palindrome (newmono, oldmono))    /* a palindrome */
  98.         return (0);
  99.  
  100.     if (strcmp (newmono, oldmono) == 0) {    /* case shifted */
  101.         printf ("Case changes only.  ");
  102.         return (0);
  103.     }
  104.     if (similiar (newmono, oldmono))    /* jumbled version */
  105.         return (0);
  106.  
  107.     if (simple (old, new))            /* keyspace size */
  108.         return (0);
  109.  
  110.     strcpy (wrapped, oldmono);
  111.     strcat (wrapped, oldmono);
  112.     if (strstr (wrapped, newmono)) {
  113.         printf ("Rotated.  ");
  114.         return (0);
  115.     }
  116.     return (1);
  117. }
  118.  
  119. /*
  120.  * can't be a palindrome - like `R A D A R' or `M A D A M'
  121.  */
  122.  
  123. /*ARGSUSED*/
  124. int    palindrome (old, new)
  125. char    *old;
  126. char    *new;
  127. {
  128.     int    i, j;
  129.  
  130.     i = strlen (new);
  131.  
  132.     for (j = 0;j < i;j++)
  133.         if (new[i - j - 1] != new[j])
  134.             return (0);
  135.  
  136.     printf ("A palindrome.  ");
  137.     return (1);
  138. }
  139.  
  140. /*
  141.  * more than half of the characters are different ones.
  142.  */
  143.  
  144. /*ARGSUSED*/
  145. int    similiar (old, new)
  146. char    *old;
  147. char    *new;
  148. {
  149.     int    i, j;
  150.     char    *strchr ();
  151.  
  152.     for (i = j = 0;new[i] && old[i];i++)
  153.         if (strchr (new, tolower (old[i])))
  154.             j++;
  155.  
  156.     if (i >= j * 2)
  157.         return (0);
  158.  
  159.     printf ("Too similiar.  ");
  160.     return (1);
  161. }
  162.  
  163. /*
  164.  * a nice mix of characters.
  165.  */
  166.  
  167. /*ARGSUSED*/
  168. int    simple (old, new)
  169. char    *old;
  170. char    *new;
  171. {
  172.     int    digits = 0;
  173.     int    uppers = 0;
  174.     int    lowers = 0;
  175.     int    others = 0;
  176.     int    size;
  177.     int    i;
  178.  
  179.     for (i = 0;new[i];i++) {
  180.         if (isdigit (new[i]))
  181.             digits++;
  182.         else if (isupper (new[i]))
  183.             uppers++;
  184.         else if (islower (new[i]))
  185.             lowers++;
  186.         else
  187.             others++;
  188.     }
  189.  
  190.     /*
  191.      * The scam is this - a password of only one character type
  192.      * must be 8 letters long.  Two types, 7, and so on.
  193.      */
  194.  
  195.     size = 9;
  196.     if (digits) size--;
  197.     if (uppers) size--;
  198.     if (lowers) size--;
  199.     if (others) size--;
  200.  
  201.     if (size <= i)
  202.         return 0;
  203.  
  204.     printf ("Too Simple.  Use a longer password, or a mix of upper\n");
  205.     printf ("and lower case letters and numerics.  ");
  206.     return 1;
  207. }
  208.